<template>
  <div v-if="verifyData" class="flex-center dragverify-modal">
    <div class="dragverify-cont">
      <div class="dragverify-img-cont">
        <img class="dragverify-bg-img no-large" :src="verifyData.back_img_data" alt="" />
        <img
          :style="{ left: left + 'px', top: verifyData.y / 2 + 'px' }"
          class="dragverify-move-img no-large"
          :src="verifyData.cover_img_url"
        />

        <div v-if="status !== 0" class="flex-center-wrap dragverify-result-notice">
          <div v-if="status === 1" class="flex-center-wrap dragverify-result-success">
            <div class="flex-center-wrap">
              <i class="icon icon-zu703 dragverify-result-icon"></i>
            </div>
            <div>
              验证通过
            </div>
          </div>

          <div v-if="status === 2" class="flex-center-wrap dragverify-result-fail">
            <div class="flex-center-wrap">
              <i class="icon icon-zu704 dragverify-result-icon"></i>
            </div>
            <div>
              验证失败
            </div>
            <div class="dragverify-result-text">拖动下方滑块完成上方拼图</div>
          </div>
        </div>
      </div>
      <div class="flex-center dragverify-area">
        <div class="flex-center gray9 dragverify-btn-area">
          <span v-if="isShowDragAreaText">拖动左边滑块完成上方拼图</span>
          <div
            @touchstart="touchstart"
            @mousedown="mousedown"
            :style="{ transform: 'translate3d(' + left + 'px,0,0)' }"
            class="flex-center dragverify-btn"
          >
            <div class="dragverify-line"></div>
            <div class="dragverify-line"></div>
            <div class="dragverify-line"></div>
          </div>

          <div :style="{ width: left + 6 + 'px' }" class="dragverify-slide-bg"></div>
        </div>
      </div>
      <div class="flex-wrap flex flex-justify-between dragverify-icon-cont">
        <i @click="refresh" class="dragverify-icon iconfont icon-zu695"></i>
        <i @click="close" class="dragverify-icon iconfont icon-guanbi1"></i>
      </div>
    </div>
  </div>
</template>
<script>
import { sliderCode, verifySlider } from '@/api/exam'
export default {
  name: 'dragVerify',
  data() {
    return {
      verifyData: null,

      //验证码图片宽度
      width: 276,
      //划款宽度
      slideWidth: 66,
      //左右两边的区域
      padding: 12,

      //拖拽x坐标
      left: 0,
      //记录滑块开始的距离
      startX: 0,

      //当前滑块的状态 0 - 未拖动，初始化  1 - 验证通过   2- 验证失败
      status: 0,

      //滑块移动的flag
      isMove: false,
      //是否验证结束，如果结束，就不能再拖动了，只能刷新
      isDragEnd: false,

      //用于标记是因为刷新触发的获取操作，如果不是刷新获取的，就是第一次进来就获取的，如果这个时候提示操作频繁，需要关掉组件
      isRefresh: false
    }
  },
  computed: {
    //显示拖动区域的文案，只有初始状态下显示
    isShowDragAreaText() {
      return !this.isMove && this.status === 0
    }
  },
  methods: {
    getDragVerifyCode() {
      sliderCode({ from: 'web' })
        .then(res => {
          if (+res.errcode !== 0) {
            this.$message.warning(res.errmsg)
            if (!this.isRefresh) this.close()
            return
          }
          this.verifyData = res.data || null
        })
        .catch(e => {})
        .finally(() => {
          this.isRefresh = false
        })
    },

    //发起验证
    verify() {
      verifySlider({ x: this.left * 2, from: 'web' })
        .then(res => {
          if (+res.errcode === 0) {
            this.status = 1
            this.$message.success('操作成功')
            this.$emit('success')
          } else {
            this.status = 2
            this.$emit('fail')
            setTimeout(this.refresh, 1000)
          }
        })
        .catch(() => {})
    },

    touchstart(e) {
      if (this.isDragEnd) return

      this.isMove = true

      this.startX = e.changedTouches[0].clientX
    },
    touchend() {
      if (this.isDragEnd) return

      if (this.isMove) {
        this.verify()
        this.isDragEnd = true
      }
    },
    touchmove(e) {
      if (this.isDragEnd) return
      if (!this.isMove) return

      let { startX, width, slideWidth, padding } = this

      let left = e.changedTouches[0].clientX - startX
      let max = width - slideWidth - padding

      this.left = left < 0 ? 0 : left > max ? max : left
    },
    mousedown(e) {
      if (this.isDragEnd) return

      this.isMove = true

      this.startX = e.clientX
    },
    mouseup() {
      if (this.isDragEnd) return

      if (this.isMove) {
        this.verify()
        this.isDragEnd = true
      }
    },
    mousemove(e) {
      if (this.isDragEnd) return
      if (!this.isMove) return

      let { startX, width, slideWidth, padding } = this

      let left = e.clientX - startX
      let max = width - slideWidth - padding

      this.left = left < 0 ? 0 : left > max ? max : left
    },
    //刷新
    refresh() {
      if (this.status === 1) return

      this.status = 0
      this.left = 0
      this.isMove = false
      this.isDragEnd = false

      this.isRefresh = true

      this.getDragVerifyCode()
    },
    //关闭
    close() {
      if (this.status === 1) return
      this.$emit('close')
    }
  },
  created() {
    if (typeof window !== 'undefined') {
      this.getDragVerifyCode()
    }
  },

  mounted() {
    document.addEventListener('touchend', this.touchend, false)
    document.addEventListener('touchmove', this.touchmove, false)
    document.addEventListener('mouseup', this.mouseup, false)
    document.addEventListener('mousemove', this.mousemove, false)
  }
}
</script>
<style scoped>
.dragverify-modal {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 9999;
  background: rgba(0, 0, 0, 0.4);
}

.dragverify-cont {
  position: absolute;
  width: 276px;
  height: 250px;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  background: white;
  border-radius: 10px;
  overflow: hidden;
}

.dragverify-img-cont {
  position: relative;
  width: 100%;
  height: 142px;
  overflow: hidden;
}

.dragverify-bg-img {
  width: 100%;
  height: 100%;
}

.dragverify-move-img {
  position: absolute;
  opacity: 0.4;
  width: 66px !important;
  height: 66px;
}

.dragverify-area {
  height: 68px;
  border-bottom: 1px solid #f4f4f5;
}

.dragverify-btn-area {
  position: relative;
  width: 252px;
  height: 44px;
  border-radius: 6px;
  font-size: 14px;
  overflow: hidden;
  background: #e5e7e9;
}

.dragverify-btn {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  height: 100%;
  width: 52px;
  border-radius: 6px;
  cursor: pointer;
  background: white;
  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.16);
  border: 1px solid #e2e6eb;
}

.dragverify-slide-bg {
  position: absolute;
  left: 0;
  top: 0;
  background: #3085ef;
  height: 100%;
}

.dragverify-line {
  margin: 0 2px;
  width: 4px;
  height: 20px;
  background: #3085ef;
  border-radius: 4px;
}

.dragverify-icon-area {
  height: 36px;
}

.dragverify-icon-cont {
  padding: 10px 16px 0;
}

.dragverify-icon {
  color: #bbbbbb;
  font-size: 16px;
  cursor: pointer;
}

.dragverify-result-notice {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 26px;
  background: rgba(0, 0, 0, 0.37);
  font-size: 12px;
}

.dragverify-result-fail {
  color: #ff6868;
}

.dragverify-result-success {
  color: #00ff90;
}

.dragverify-result-text {
  margin-left: 8px;
  opacity: 0.8;
  color: white;
}

.dragverify-result-icon {
  margin: 0 4px 0 12px;
  font-size: 10px;
}
</style>
